package com.Akronmcp.hta.obj;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.bukkit.Bukkit;

import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;

import com.Akronmcp.hta.main.HM;
import com.Akronmcp.hta.main.HSender;

import me.clip.placeholderapi.PlaceholderAPI;

public class HopTitle extends HPar2{

	
	String type = "TITLE";
  
	
	private int fadein = 5;
	private int fadeout = 5;
	
	int priority = 10;
	//弹幕优先级
	
	String ttext = "";
	//临时文本,用于输出
	//text用于储存
	
	static Map<String,Integer> sdpT = new HashMap<String,Integer>();//正在send-Title的玩家名和对应title的优先级
	static Map<String,Integer> sdpsT = new HashMap<String,Integer>();//正在send-subTitle的玩家名
	static Map<String,Integer> sdpA = new HashMap<String,Integer>();//正在send-actionbar的玩家名
    //一对组合,我称为根,用来识别正在占用屏幕运行的输出线程,根生线程启,根除线程灭
	
	public HopTitle()
	{
		
	}
	
	
	public HopTitle(HManager hta) 
	{
		super(hta);
	}

	/**设置弹幕类型*/
	public void setType(String type)
	{
		this.type = type.toUpperCase();
	}
	
	public String getType() 
	{
		return type;
	}

	
	public void setFadein(int fadein)
	{
		this.fadein = fadein;
	}
		
	public void setFadeout(int fadeout)
	{
		this.fadeout = fadeout;
	}
	
	public int getFadein() {
		return fadein;
	}

	public int getFadeout() {
		return fadeout;
	}

	/**设置3大时间*/
	public void set3Time(int fadein,int time,int fadeout)
	{
		this.setFadein(fadein);
		this.staytime = time;
		this.setFadeout(fadeout);
	}
	
    @Override
	public void setText(String text)
	{
	   this.text = text;
	   setTtext(text);
	   
	}

	public String toString()
	{
		return this.text;
	}
	 
	
	/**发送HopTitle弹幕给所有玩家*/
	public void sendToAll()
	{
		Collection<? extends Player> pl = Bukkit.getOnlinePlayers();
		if(pl.isEmpty())
		return;
		
	    send(new ArrayList<Player>(pl));
	}
 	
	/**发送HopTitle弹幕(主程序)*/
	public void send(List<Player> pl)
    {//send主程序
		
		if(pl==null||pl.isEmpty()) 
		return;
		
		if(module!=null)
		if(!iscopyedmodule||module.equals("auto"))
		this.setModule(module); 
		 
		boolean isnotx = false;
		if(sl.isEmpty()&&gethoptypes().isEmpty())
		isnotx = true;
		
		Map<String,Integer> sdp = null;
				
		HopTitle htl = this;
		
		if(type.equals("TITLE"))
		{sdp = sdpT;}
		if(type.equals("SUBTITLE"))
		{sdp = sdpsT;}
		if(type.equals("ACTIONBAR")) 
		{sdp = sdpA;}
		
	    	
	    final Map<String,Integer> sdp2 = sdp;
	    //储存正在sending对应种类的title的Playername集合
	    
	    final List<Player> pl2 = new ArrayList<Player>(pl);
	    List<Player> rpl = new ArrayList<Player>();
	    
		for(Player p2:pl2)
		{//前置优先级判断
			String name = p2.getName();
		    if(sdp.containsKey(name))
		    {
		       if(sdp.get(name)>=priority)
		       {
		    	   rpl.add(p2);
		    	   continue;
		       }//else
		    
		       sdp2.remove(name);//移除其他
		       
		       if(!isnotx)//无特效无需植根
		       sdp2.put(name,priority);   
		    }else
		    {//植下根
		    	if(!isnotx)
		    	sdp2.put(name,priority);
		    }
		}
	    
		for(Player pa:rpl)
		{
			pl2.remove(pa);
		}
	    
	    if(isnotx)
	    {//无特效send
	    	for(Player p2:pl2)
	    	{
	    		Player pp = p2;
	    		
	    		if(papi)
	    		ttext = PlaceholderAPI.setPlaceholders(pp, text);
	    		
	    		hta.sendTitle(this, p2);
	    	}
	    	
	    	return;
	    }
	    
	    		//_特效send------------------
				 Map<String,Parg> ppa = new HashMap<String,Parg>();
				 List<String> sl2 = new ArrayList<String>();//临时分配给玩家的list
				 
				 
				 for(Player p2:pl2)
		 		 {	//每个玩家分配一个list等对应参数
					 
		 		   HSender.sendTitle(p2, null, "TIMES",0,
    	    		ticktime+10,getFadeout());
		 		   //消去fade时间利于观察
		 		   
		 		    Player pp = p2;
		 		   
		 		   if(papi)//解析papi
				   {
		 		      ttext = PlaceholderAPI.setPlaceholders(pp, text);
		 			   
		 		     sl2 = new ArrayList<String>();	
		 			   int j = 0;
		 			   //遍历index
		 		   
		 		 if(!gethoptypes().isEmpty()) 
		 		 for(String type:gethoptypes())
		 		 {//遍历闪烁种类s
		 			 
		 		   String[] thta2 =  PlaceholderAPI.setPlaceholders(pp,
		 				   Arrays.asList(getHopargs().get(j))).toArray(new String[0]);
		 		   //解析所有参数
		 		   j++;
		 		   
		 		   
		 		       try {
		 		    	   
					  HDancer.Dance(sl2,type,(int) ticktime,
							   ttext,thta2);
					
				        }catch (Exception e) 
		 		        {e.printStackTrace();}
				        //生成特效list
		 		       
		 		 }
		 		   
		 		  
		 		}else
		 		{//无papi则默认
		 			
		 			sl2.addAll(sl);
		 		}
		 		   
		 		   
		 		  
		 		  Parg pa1 = new Parg();//每个玩家对应的list等参数
		 		  pa1.tcycle = getCycle();
		 		  pa1.index = 0;
		 		  pa1.tsl = sl2;
		 		  if(endbyhop)
		 		  {
		 			  pa1.times = sl2.size()*getCycle();
		 			  pa1.ttimes = pa1.times;
		 			  pa1.sectime =  (int)((pa1.times*ticktime)/20);
		 		  }
		 		  
		 		  
		 		  ppa.put(p2.getName(),pa1); 
		 		  
		 		 if(type.equals("TITLE"))
		 		 HSender.sendTitle(p2," ","SUBTITLE");
		 		 //清除残余subt
			}//for
 	     
	      if(endbyhop)
	      {
	    	  setStayTime(ticktime*sl.size());
	      }
	      //设置时间以对应,意义不大
	     
	      
	    
		new BukkitRunnable() {
			
			
           float time = htl.getStayTime();
           //总时间
           int tcycle = getCycle();
           //循环次数
           int index = 0;
           //下标
           float ticktime = htl.getTickTime();
           //闪动间隔
           float times = time/ticktime; 
           //闪动总次数
           float ttimes = times;
           //闪动剩余次数
           int secTime = (int)(time/20);
           
           boolean isend = false;
           List<String> tsl = sl;
           
           int size = sl.size();
           
           public void run() 
           {//重写run方法
       
               if (ttimes > 0)
               {//计时条件,如果父对象不sending,则结束
            	   
               	  
               		   
               	   
                   for(Player p3:pl2)
                   {//遍历玩家
                	     String name2 = p3.getName();
                	     Parg pa = ppa.get(name2);
                         ttext = pa.ttext;
                  if(endbyhop)  	 
                 {   	 
                   	  float tttimes = pa.ttimes;
                   	  
                   	  if(tttimes < 1)
                   	  {//次数为0则跳过
                   		  if(!ttext.equals(" "))
                   		  {
                   			 ttext = " ";
                   			ppa.get(name2).ttext = ttext;  
                   			sdp2.remove(name2);
                   		  }
                   		  
                   		  continue;
                   	  }else
                   	  {
                   		  ttimes = tttimes;
                   		  
                   	  }
                   	  secTime = pa.sectime;
                   	  times = pa.times;
                }   	  
                   	  
                   	  isend = pa.isend;
                   	  
                   	 
					if(!isend)
                   	  {//结束循环前有意义
                   		  
                   	  tsl = pa.tsl;
                   	  tcycle = pa.tcycle;
                   	  index = pa.index;
                   	  
                   	  size = tsl.size();  
                   	  }   	  
                   	  
                     
               	     if(!isend && (!tsl.isEmpty()) && tcycle > 0)
                     {//开始闪烁,遍历集合
 	  
               	      String str = tsl.get(index); 
	               	
	               	  str =  str.replace("&s", String.valueOf((int)((ttimes/20)*ticktime)));
	               	  str =  str.replace("&S", String.valueOf(secTime - (int)((ttimes/20)*ticktime)));  	 
               	      
               	    if((str!=null)&&!str.equals("-"))
                     {//设置文本
               	    	ttext = str;
                     }
                    	
               	    
               	    
               	 if(sdp2.containsKey(name2))//////
                 {//接近send部分确保立即性
    			    	
           	      if(sdp2.get(name2)>priority)
           	      {
           	    	ppa.get(name2).ttext = " ";
           	    	ppa.get(name2).ttimes = 0;
           	    	ttimes = 0;
           	    	continue;
           	     	  //如果优先级被覆盖,则取消
           	      }else
           	      {
           	    	  HSender.sendTitle(p3,ttext,type);
           	      }
                 }else
                 {
                	  pa.ttext = " ";
           	    	  pa.ttimes = 0;
           	    	  ttimes = 0;
          	     	  continue;
          	     	  
          	     	  //根除则灭
                 }//////
               
                        	    
  	  
                    }else//如果集合空或停止循环
                    {//特效结束后用默认文本,继续循环
                    
	                    if(!isend) 
	                   	if(papi)
	                   	{	
	                   	  ttext = PlaceholderAPI.setPlaceholders(p3,text);  
	                   	}else {ttext = text;}
	                   	
	                   	
	                   	
	                   	if(sdp2.containsKey(name2))//////
	                    {//接近send部分确保立即性
	       			    	
	              	      if(sdp2.get(name2)>priority)
	              	      {
	              	    	pa.ttext = " ";
	              	    	pa.ttimes = 0;
	              	    	 ttimes = 0;
	              	    	continue;
	              	     	  //如果优先级被覆盖,则取消
	              	      }else
	              	      {
	              	    	  HSender.sendTitle(p3,ttext,type);
	              	      }
	                    }else
	                    {
	                   	  	  pa.ttext = " ";
	              	    	  pa.ttimes = 0;
	              	    	  ttimes = 0;
	             	     	  continue;
	             	     	  //根除则灭
	                    }//////
                    	 
                   	
                   	
                   }
                   
               	     
                  
                    if(!isend)
                    {///
                    if(tcycle>=1)     	
                    {//
               	    if(index+1 < size)
                      {
                  	    index++;
                  	  
                      }else 
                      {//循环一次后
                  	    index = 0;
                  	    tcycle--;

                      }
                    }else {isend = true;} //
                   	
                   	    pa.tcycle = tcycle;
                  		pa.index = index;
                  		pa.isend = isend;  
                  		pa.ttext = ttext;  
                   	
                    }///
                         		 
                  	  
                  	  if(endbyhop)
                  	  {
                  		                    	          	  
                  	  pa.ttimes = ttimes -1;
                  	  
                  	  ttimes = 2;
                  	  //还原ttimes,让线程继续,说明还有其他玩家没有end
                  	  //当所有玩家都ttimes<1,则最后一次for遍历不会执行到此处
                  	  //直接导致ttimes被减少成0
                  	  }
                   
                   }
               	  
                   ttimes--;
                   
               }
               else 
               {//时间到或不在线
                    
                  for(Player p4:pl2)
                  {
                	  
             		  sdp2.remove(p4.getName());
                  }
                  
                   cancel();//终止
               }
           } 
          
       }.runTaskTimerAsynchronously(HM.getPlugin(HM.class), 0L, ticktime);	   
	
       sendSubtext(pl);
	   	 //伴随文本
	}
	
	 
	public void setTtext(String text) {
		
		this.ttext = text;
	}

	/**直接给玩家发送一串临时弹幕*/
	public static void sendBy(Player p,String text)
	{
		sendBy(p,text ,"TITLE");
	}
	/**直接给玩家发送一串临时弹幕*/
	public static void sendBy(Player p,String text,String ac)
	{
		HSender.sendTitle(p, null, "TIMES", 5, 60, 5);
		HSender.sendTitle(p, text, ac);
	}
	/**直接给玩家发送一串临时弹幕*/
	public void sendBy(Player p,String text,String ac,int fi,int st,int fo)
	{
		HSender.sendTitle(p, null,"TIMES", fi, st, fo);
		HSender.sendTitle(p, text, ac);
	}
	
	/**加入引擎列表*/
	public void addToList(String id)
	{
		this.id = id;
		hta.addTitle(this);
		
	}
	
	/**设置弹幕优先级*/
	public void setPriority(int i)
	{
		priority = i;
	}
	
	public int getPriority()
	{
		return priority;
	}
	
	/**获取临时文本*/
	public String getTText()
	{
		return ttext;
	}

	/**每个玩家对应的弹幕参数*/
	class Parg
	{
	   List<String> tsl;
	   int index = 0;
	   int tcycle = 1;
	   String ttext;
	   
	   float ttimes;
	   float times;
	   int sectime;
	
	   boolean isend =false;
	}

	/**直接给玩家发送一串临时弹幕并通过模板生成特效*/
	public static void sendBy(List<Player> pl,String text,String type,String module,boolean ispapi)
	{
		
	   HopTitle ht = new HopTitle();
	   
	   ht.setPapi(ispapi);
	   
	   ht.setType(type);
	   ht.setText(text); 
	   ht.setModule(module);
	  
	   for(Player p:pl)
       ht.send(p);
       	   
	}
	/**直接给玩家发送一串临时弹幕并通过模板生成特效*/
	public static void sendBy(Player p,String text,String ac,String module,boolean ispapi)
	{
		sendBy(Arrays.asList(p),text,ac,module,ispapi);
	}
	
	/**直接给玩家发送一串临时弹幕并通过模板生成特效*/
	public static void sendtoallBy(String text,String ac,String module,boolean ispapi)
	{
		sendBy(new ArrayList<Player>(Bukkit.getOnlinePlayers()),text,ac,module,ispapi);
	}
	
}
